package com.zlict.admin.service.impl;

import java.text.SimpleDateFormat;
import java.util.*;
import java.text.ParseException;

import com.zlict.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.commons.lang3.StringUtils;
import com.zlict.admin.mapper.RdWorkhoursMapper;
import com.zlict.admin.domain.RdWorkhours;
import com.zlict.admin.service.IRdWorkhoursService;
import com.zlict.system.mapper.SysUserMapper;
import com.zlict.common.core.domain.entity.SysUser;

/**
 * 考勤工时Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-06-11
 */
@Service
public class RdWorkhoursServiceImpl implements IRdWorkhoursService 
{
    @Autowired
    private RdWorkhoursMapper rdWorkhoursMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 查询考勤工时
     * 
     * @param id 考勤工时主键
     * @return 考勤工时
     */
    @Override
    public RdWorkhours selectRdWorkhoursById(Long id)
    {
        return rdWorkhoursMapper.selectRdWorkhoursById(id);
    }

    /**
     * 查询考勤工时列表
     * 
     * @param rdWorkhours 考勤工时
     * @return 考勤工时
     */
    @Override
    public List<RdWorkhours> selectRdWorkhoursList(RdWorkhours rdWorkhours)
    {
        return rdWorkhoursMapper.selectRdWorkhoursList(rdWorkhours);
    }

    @Override
    public List<RdWorkhours> selectRdWorkhoursByUserList(RdWorkhours rdWorkhours) {
        return rdWorkhoursMapper.selectRdWorkhoursByUserList(rdWorkhours);
    }

    /**
     * 新增考勤工时
     * 
     * @param rdWorkhours 考勤工时
     * @return 结果
     */
    @Override
    public int insertRdWorkhours(RdWorkhours rdWorkhours)
    {
        // 校验用户是否存在
        SysUser sysUser = sysUserMapper.selectUserByUserName(rdWorkhours.getUserName());
        if (sysUser == null) {
            throw new RuntimeException("用户【" + rdWorkhours.getUserName() + "】不存在，无法新增考勤工时记录！");
        }
        
        // 校验同一用户同一日期是否已存在记录
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        RdWorkhours query = new RdWorkhours();
        query.setUserName(rdWorkhours.getUserName());
        query.setWorkDate(rdWorkhours.getWorkDate());
        List<RdWorkhours> existingRecords = rdWorkhoursMapper.selectRdWorkhoursList(query);
        if (!existingRecords.isEmpty()) {
            throw new RuntimeException("用户【" + rdWorkhours.getUserName() + "】在日期【" + sdf.format(rdWorkhours.getWorkDate()) + "】已存在考勤工时记录！");
        }
        
        rdWorkhours.setCreateTime(DateUtils.getNowDate());
        return rdWorkhoursMapper.insertRdWorkhours(rdWorkhours);
    }

    /**
     * 修改考勤工时
     * 
     * @param rdWorkhours 考勤工时
     * @return 结果
     */
    @Override
    public int updateRdWorkhours(RdWorkhours rdWorkhours)
    {
        // 校验同一用户同一日期是否已存在其他记录
        RdWorkhours query = new RdWorkhours();
        query.setUserName(rdWorkhours.getUserName());
        query.setWorkDate(rdWorkhours.getWorkDate());
        List<RdWorkhours> existingRecords = rdWorkhoursMapper.selectRdWorkhoursList(query);
        if (!existingRecords.isEmpty() && !existingRecords.get(0).getId().equals(rdWorkhours.getId())) {
            throw new RuntimeException("用户【" + rdWorkhours.getUserName() + "】在日期【" + rdWorkhours.getWorkDate() + "】已存在其他考勤工时记录！");
        }
        
        rdWorkhours.setUpdateTime(DateUtils.getNowDate());
        return rdWorkhoursMapper.updateRdWorkhours(rdWorkhours);
    }

    /**
     * 批量删除考勤工时
     * 
     * @param ids 需要删除的考勤工时主键
     * @return 结果
     */
    @Override
    public int deleteRdWorkhoursByIds(Long[] ids)
    {
        return rdWorkhoursMapper.deleteRdWorkhoursByIds(ids);
    }

    /**
     * 删除考勤工时信息
     * 
     * @param id 考勤工时主键
     * @return 结果
     */
    @Override
    public int deleteRdWorkhoursById(Long id)
    {
        return rdWorkhoursMapper.deleteRdWorkhoursById(id);
    }

    /**
     * 导入考勤工时数据
     * 
     * @param file 导入文件
     * @return 结果
     */
    @Override
    public Map<String,Object> importData(MultipartFile file) {
        try {
            // 验证文件
            if (file == null || file.isEmpty()) {
                throw new RuntimeException("请选择要导入的文件");
            }

            // 读取Excel文件
            Workbook workbook = WorkbookFactory.create(file.getInputStream());
            Sheet sheet = workbook.getSheetAt(0);
            if (sheet == null || sheet.getLastRowNum() < 1) {
                throw new RuntimeException("导入数据为空");
            }

            // 获取表头
            Row headerRow = sheet.getRow(0);
            if (headerRow == null || headerRow.getLastCellNum() < 3) {
                throw new RuntimeException("文件格式不正确，至少需要工号、姓名和年月列");
            }

            // 验证工号列和姓名列
            if (!"工号".equals(getCellValueAsString(headerRow.getCell(0))) || 
                !"姓名".equals(getCellValueAsString(headerRow.getCell(1)))) {
                throw new RuntimeException("文件格式不正确，第一列必须为工号，第二列必须为姓名");
            }

            // 收集错误信息
            List<String> errorMessages = new ArrayList<>();
            // 用于存储要导入的数据
            List<RdWorkhours> importList = new ArrayList<>();

            // 处理每一行数据
            for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                Row row = sheet.getRow(rowIndex);
                if (row == null) continue;

                String employeeNo = getCellValueAsString(row.getCell(0));
                String employeeName = getCellValueAsString(row.getCell(1));
                String monthStr = getCellValueAsString(row.getCell(2));

                // 验证工号格式
                if (StringUtils.isEmpty(employeeNo)) {
                    errorMessages.add(String.format("第%d行：工号不能为空", rowIndex + 1));
                    continue;
                }

                // 验证工号是否存在
                SysUser user = sysUserMapper.selectUserByUserName(employeeNo);
                if (user == null) {
                    errorMessages.add(String.format("第%d行：工号[%s]不存在", rowIndex + 1, employeeNo));
                    continue;
                }

                // 验证年月格式
//                if (StringUtils.isEmpty(monthStr) || !monthStr.matches("\\d{4}-\\d{2}")) {
//                    errorMessages.add(String.format("第%d行：年月格式不正确，请使用yyyy-MM格式", rowIndex + 1));
//                    continue;
//                }

                // 处理每个日期的工时数据
                for (int i = 2; i < headerRow.getLastCellNum(); i++) {
                    String dayStr = getCellValueAsString(headerRow.getCell(i));
                    String workHoursStr = getCellValueAsString(row.getCell(i));
                    
                    if (!StringUtils.isEmpty(workHoursStr)) {
                        try {
                            // 解析日期
                            String dateStr =  dayStr;
                            Date workDate = new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
                            
                            // 解析工时数据
                            double workHours = Double.parseDouble(workHoursStr);
                            
                            // 检查是否已存在该日期的工时记录
                            RdWorkhours query = new RdWorkhours();
                            query.setUserName(employeeNo);
                            query.setWorkDate(workDate);
                            List<RdWorkhours> existList = rdWorkhoursMapper.selectRdWorkhoursList(query);
                            if (!existList.isEmpty()) {
                                errorMessages.add(String.format("第%d行：工号[%s]在日期[%s]已存在工时记录", 
                                    rowIndex + 1, employeeNo, dateStr));
                                continue;
                            }
                            
                            // 创建工时记录
                            RdWorkhours workhours = new RdWorkhours();
                            workhours.setUserName(employeeNo);
                            workhours.setWorkDate(workDate);
                            workhours.setWorkhours(workHours);
                            workhours.setCreateTime(DateUtils.getNowDate());
                            importList.add(workhours);
                        } catch (ParseException e) {
                            errorMessages.add(String.format("第%d行：工号[%s]的日期格式不正确", 
                                rowIndex + 1, employeeNo));
                        } catch (NumberFormatException e) {
                            errorMessages.add(String.format("第%d行：工号[%s]的工时数据格式不正确", 
                                rowIndex + 1, employeeNo));
                        }
                    }
                }
            }

            // 如果有错误信息，抛出异常
            if (!errorMessages.isEmpty()) {
               // throw new RuntimeException(String.join("\n", errorMessages));
                Map<String,Object> map= new HashMap<String,Object>();
                map.put("successNum",0);
                map.put("failureNum",errorMessages.size());
                map.put("failureMsg",String.join("\n", errorMessages));

                return map;
            }

            // 批量保存数据
            int successCount = 0;
            if (!importList.isEmpty()) {
                for (RdWorkhours workhours : importList) {
                    successCount += rdWorkhoursMapper.insertRdWorkhours(workhours);
                }
            }

            Map<String,Object> map= new HashMap<String,Object>();
            map.put("successNum",successCount);
            map.put("failureNum",errorMessages.size());
            map.put("failureMsg",String.join("\n", errorMessages));

            return map;
        } catch (Exception e) {
            throw new RuntimeException("导入失败：" + e.getMessage());
        }
    }

    /**
     * 获取单元格的值
     */
    private String getCellValueAsString(Cell cell) {
        if (cell == null) {
            return "";
        }
        String value = "";
        switch (cell.getCellType()) {
            case STRING:
                value = cell.getStringCellValue();
                break;
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    value = new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
                } else {
                    value = String.valueOf(cell.getNumericCellValue());
                }
                break;
            case BOOLEAN:
                value = String.valueOf(cell.getBooleanCellValue());
                break;
            case FORMULA:
                value = cell.getCellFormula();
                break;
            default:
                value = "";
        }
        return value;
    }
}
